{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Using Tensorboard\n",
    "-----------------------------\n",
    "We illustrate the various uses of Tensorboard in this script.\n",
    "\n",
    " 1. Visualizing a scalar value.\n",
    " 2. Visualizing a histogram of values.\n",
    " 3. Adding a custom matplotlib graph to Tensorboard\n",
    "\n",
    "We start by loading the necessary libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import io\n",
    "import time\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Start a graph session:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "sess = tf.Session()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We start by creating an object on our graph that will write the Tensorboard summaries to a file.  When we call this operation we will then be able to view the updated graph instantly in Tensorboard.\n",
    "\n",
    "We run the script `01_using_tensorboard.py` from the command line via:\n",
    "\n",
    "`$ python3 01_using_tensorboard.py`\n",
    "\n",
    "We then start the Tensorboard application by running the command:\n",
    "\n",
    "`$ tensorboard --logdir=\"tensorboard\"`\n",
    "\n",
    "Then we navigate our browser to the folling link:\n",
    "\n",
    "http://127.0.0.0:6006\n",
    "\n",
    "Note that we can specify a different port if need be by passing a `--port 6007` command (for running on port 6007."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a visualizer object\n",
    "summary_writer = tf.summary.FileWriter('tensorboard', tf.get_default_graph())\n",
    "\n",
    "# Create tensorboard folder if not exists\n",
    "if not os.path.exists('tensorboard'):\n",
    "    os.makedirs('tensorboard')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tensorboard will be viewable _*as*_ your program is running, so we should slow down our algorithm so that we have time to run the above tensorboard commands and load tensorboard."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Wait a few seconds for user to run tensorboard commands\n",
    "time.sleep(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Set the algorithm parameteres"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "batch_size = 50\n",
    "generations = 100"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For the model, we will create a linear regression fit to generated data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create sample input data\n",
    "x_data = np.arange(1000)/10.\n",
    "true_slope = 2.\n",
    "y_data = x_data * true_slope + np.random.normal(loc=0.0, scale=25, size=1000)\n",
    "\n",
    "# Split into train/test\n",
    "train_ix = np.random.choice(len(x_data), size=int(len(x_data)*0.9), replace=False)\n",
    "test_ix = np.setdiff1d(np.arange(1000), train_ix)\n",
    "x_data_train, y_data_train = x_data[train_ix], y_data[train_ix]\n",
    "x_data_test, y_data_test = x_data[test_ix], y_data[test_ix]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we declare the placeholders, variables, model operations, loss, and optimization function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Declare placeholders\n",
    "x_graph_input = tf.placeholder(tf.float32, [None])\n",
    "y_graph_input = tf.placeholder(tf.float32, [None])\n",
    "\n",
    "# Declare model variables\n",
    "m = tf.Variable(tf.random_normal([1], dtype=tf.float32), name='Slope')\n",
    "\n",
    "# Declare model\n",
    "output = tf.multiply(m, x_graph_input, name='Batch_Multiplication')\n",
    "\n",
    "# Declare loss function (L1)\n",
    "residuals = output - y_graph_input\n",
    "l1_loss = tf.reduce_mean(tf.abs(residuals), name=\"L1_Loss\")\n",
    "\n",
    "# Declare optimization function\n",
    "my_optim = tf.train.GradientDescentOptimizer(0.01)\n",
    "train_step = my_optim.minimize(l1_loss)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we show how to log a scalar variable with Tensorboard."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Visualize a scalar\n",
    "with tf.name_scope('Slope_Estimate'):\n",
    "    tf.summary.scalar('Slope_Estimate', tf.squeeze(m))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a href=\"url\"><img src=\"https://github.com/nfmcclure/tensorflow_cookbook/raw/master/11_More_with_TensorFlow/images/01_tensorboard1.png\" align=\"left\" height=\"450\" width=\"450\" ></a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we show how to visualize a vector of parameters with a histogram summary."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Visualize a histogram (errors)\n",
    "with tf.name_scope('Loss_and_Residuals'):\n",
    "    tf.summary.histogram('Histogram_Errors', l1_loss)\n",
    "    tf.summary.histogram('Histogram_Residuals', residuals)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a href=\"url\"><img src=\"https://github.com/nfmcclure/tensorflow_cookbook/raw/master/11_More_with_TensorFlow/images/01_tensorboard2.png\" align=\"left\" height=\"450\" width=\"450\" ></a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now create a summary merge operation that combines all the summary calculating operations into one."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Declare summary merging operation\n",
    "summary_op = tf.summary.merge_all()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Initialize the variables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Initialize Variables\n",
    "init = tf.global_variables_initializer()\n",
    "sess.run(init)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now optimize our linear regression.\n",
    "\n",
    "Also for every iteration we will call the summary writer to write the summaries we have created to the Tensorboard directory.\n",
    "\n",
    "(Also note that we have a `time.sleep(0.5)` in the loop.  This is to slow down the algorithm to view it in progress in Tensorboard)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Generation 10 of 100. Train Loss: 17.6, Test Loss: 19.0.\n",
      "Generation 20 of 100. Train Loss: 20.9, Test Loss: 18.8.\n",
      "Generation 30 of 100. Train Loss: 24.6, Test Loss: 18.8.\n",
      "Generation 40 of 100. Train Loss: 22.2, Test Loss: 19.4.\n",
      "Generation 50 of 100. Train Loss: 20.7, Test Loss: 19.9.\n",
      "Generation 60 of 100. Train Loss: 19.5, Test Loss: 18.9.\n",
      "Generation 70 of 100. Train Loss: 18.5, Test Loss: 19.2.\n",
      "Generation 80 of 100. Train Loss: 16.5, Test Loss: 19.2.\n",
      "Generation 90 of 100. Train Loss: 18.0, Test Loss: 18.9.\n",
      "Generation 100 of 100. Train Loss: 23.9, Test Loss: 18.8.\n"
     ]
    }
   ],
   "source": [
    "for i in range(generations):\n",
    "    batch_indices = np.random.choice(len(x_data_train), size=batch_size)\n",
    "    x_batch = x_data_train[batch_indices]\n",
    "    y_batch = y_data_train[batch_indices]\n",
    "    _, train_loss, summary = sess.run([train_step, l1_loss, summary_op],\n",
    "                             feed_dict={x_graph_input: x_batch,\n",
    "                                        y_graph_input: y_batch})\n",
    "    \n",
    "    test_loss, test_resids = sess.run([l1_loss, residuals], feed_dict={x_graph_input: x_data_test,\n",
    "                                                                       y_graph_input: y_data_test})\n",
    "    \n",
    "    if (i+1)%10==0:\n",
    "        print('Generation {} of {}. Train Loss: {:.3}, Test Loss: {:.3}.'.format(i+1, generations, train_loss, test_loss))\n",
    "\n",
    "    log_writer = tf.summary.FileWriter('tensorboard')\n",
    "    log_writer.add_summary(summary, i)\n",
    "    time.sleep(0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we will illustrate how to put a custom graph into Tensorboard.  For this example we will write the final graph of the linear regression.\n",
    "\n",
    "First we need to create a function that generates the linear plot in a protobuf format."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Create a function to save a protobuf bytes version of the graph\n",
    "def gen_linear_plot(slope):\n",
    "    linear_prediction = x_data * slope\n",
    "    plt.plot(x_data, y_data, 'b.', label='data')\n",
    "    plt.plot(x_data, linear_prediction, 'r-', linewidth=3, label='predicted line')\n",
    "    plt.legend(loc='upper left')\n",
    "    buf = io.BytesIO()\n",
    "    plt.savefig(buf, format='png')\n",
    "    buf.seek(0)\n",
    "    return(buf)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we add the image to Tensorboard."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAD8CAYAAAB0IB+mAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJztnXmYFNXV/7+3exYWUXRcEBFRQQUFAREdNQRcQFFhIpi4giuOAqO+GiLvm7zBn4kLmgQHEGcQEKKRqPgiGjdARo0ziiAo7oISBDccRVlktj6/P25f6tbtW9XVPd09Mz3n8zz19HR1Lbeq4NxTZxVEBIZhGCb7CTX1ABiGYZjMwAKfYRimlcACn2EYppXAAp9hGKaVwAKfYRimlcACn2EYppXAAp9hGKaVwAKfYRimlcACn2EYppWQ09QD0Nl///2pW7duTT0MhmGYFsXq1au/I6ID4m0XWOALIQ4FsADAQQAIQDkR3S+EmALgWgBbo5v+NxE9F91nMoCrATQAKCGiF/3O0a1bN6xatSrokBiGYRgAQoj/BNkuEQ2/HsAtRPS2EKIDgNVCiKXR3/5GRPcZA+gF4CIAxwLoDGCZEOIoImpI4JwMwzBMighswyeir4jo7ejf2wF8COAQn11GAlhIRDVE9DmA9QAGNmawDMMwTPIk5bQVQnQD0A/Am9FVE4QQ7woh5goh9o2uOwTAF9pum+E/QTAMwzBpJGGnrRBiLwCLANxERD8JIWYBuAPSrn8HgL8AuCqB440DMA4AunbtGvN7XV0dNm/ejN27dyc6VCYDtGnTBl26dEFubm5TD4VhmDgkJPCFELmQwv5RInoKAIjoG+332QCejX7dAuBQbfcu0XUuiKgcQDkADBgwIKY4/+bNm9GhQwd069YNQohEhsukGSJCdXU1Nm/ejMMPP7yph8MwTBwCm3SElLZzAHxIRH/V1h+sbfYrAO9F/14C4CIhRL4Q4nAAPQCsTHSAu3fvRkFBAQv7ZogQAgUFBfz2xTAthEQ0/FMBXA5gnRBibXTdfwO4WAjRF9KksxHAdQBARO8LIR4H8AFkhM/4ZCN0WNg3X/jZMIydqiqgogIYPBgoLGzq0UgCC3wi+jcA2//u53z2+TOAPycxLoZhmBZLVRVwxhlATQ0QCgEzZwLjxjX1qLi0QlJMmTIF9913n+fvixcvxgcffJDBETEMky6qqoC77pKfQamokMI+EgHq64EJExLbP12wwE8DLPAZJjtQmvof/iA/gwrtwYOlZq9oaJCTQFOTlQI/mRk5Hn/+859x1FFH4bTTTsPHH38MAJg9ezZOPPFEHH/88Rg1ahR27dqFyspKLFmyBL/97W/Rt29fbNiwwbodwzDNn4oKoLZWCuza2uBCu7BQmnFyc6Xgz8+Xk0BTk3UCP9kZ2Y/Vq1dj4cKFWLt2LZ577jm89dZbAIALLrgAb731Ft555x307NkTc+bMwSmnnIIRI0bg3nvvxdq1a3HkkUdat2MYpvmilMaCAiAvDwiH5WciQnvcOOCVV4A//QlYvrx5OG6bVbXMVGCbkRt7o1977TX86le/Qrt27QAAI0aMAAC89957+P3vf49t27Zhx44dGDZsmHX/oNsxDNP0KKWxtlYK+WnTgOrq5KJtCgvj75PJaJ6sE/iDB8uHpB5WOl+jrrjiCixevBjHH388Hn74YVR4vO8F3Y5hmKbHVBqrq4HJk9NzLnNySfebQNaZdAoL5U27447U3bxBgwZh8eLF+Pnnn7F9+3Y888wzAIDt27fj4IMPRl1dHR599NE923fo0AHbt2/f891rO4Zhmh9KaUzGjGPDz6e4YAGwe3fiPoJkyToNHwj2GpUI/fv3x29+8xscf/zxOPDAA3HiiScCAO644w6cdNJJOOCAA3DSSSftEfIXXXQRrr32WpSWluLJJ5/03I5hmKbBz4yilMZEzCxex6uqAoYMcTT4FSuc36uqgLlzAYoWlMnJyYBjl4iazXLCCSeQyQcffBCzjmle8DNiWhKVlURt2xKFw/KzsjJ9xysuJpIiXS7Fxc5vd94p9wGIhHD/ligAVlEAGZt1Jh2GYRg/Um1GSTZ0c/BgaTYSQoZvjhnTuHEEgQU+wzCthmTNKH52eC+bv9pWVQ4Ph4F+/dz7qlJUmSpJlZU2fIZhGBsVFVITB6SQvfLKYGGTfpE0us2/oEC+QUydCjz/vCyrIIQU9kTATTcBvXvLfSoq5O9E8jMVIeTxYIHPMEyrwQzbDmJGCZLbo74PHiy30VHaO5F7/0yGkCtY4DMMk7WY0TO2CJx4iU9BBXNFBVBX516n7PNCSC1e3z+ZaKDGwgKfYZisxMsUo4dtB0l8CiqYBw+Wwl1p+Lm5wNVXy7eIdeuARYuAUaNizUGZLLnATtsmYK+99gIAfPnllxg9erTvttOmTUu42FpFRQXOO+883/VLlizB3XffndBxGaYlESR6JmiETWGhzLb1E86FhcD06cDAgcCgQY6wB6Ttfvly+dmUZZJZ4KeIhobEm3l17twZTz75pO82yQj8IIwYMQK33XZbyo/LMM2FIBmzfhE2iVbcraqSAn3VKuDVV4Hycvn2sGBBcmGb6YAFfhw2btyIY445Bpdeeil69uyJ0aNH7xHA3bp1w+9+9zv0798fTzzxBDZs2ICzzz4bJ5xwAn7xi1/go48+AgB8/vnnKCwsRO/evfH73//edezjjjsOgJwwbr31Vhx33HHo06cPpk+fjtLSUnz55ZcYMmQIhgwZAgB46aWXUFhYiP79++PCCy/Ejh07AAAvvPACjjnmGPTv3x9PPfVU3Ot6+OGHMWHCBACy1k9JSQlOOeUUHHHEEa5J6N5778WJJ56IPn364I9//GMK7ijDZIYgZVZs2/hV3PWbCNTbQiQiv0cijnnHnFTSUcI9EEGyszK1xM201VPWUr148PnnnxMA+ve//01ERFdeeSXde++9RER02GGH0T333LNn29NPP50++eQTIiJ64403aMiQIUREdP7559P8+fOJiGjGjBnUvn37Pcc+9thjiYjogQceoFGjRlFdXR0REVVXV+85x9atW4mIaOvWrfSLX/yCduzYQUREd999N91+++30888/U5cuXeiTTz6hSCRCF154IZ177rkx17JixYo96+fNm0fjx48nIqKxY8fS6NGjqaGhgd5//3068sgjiYjoxRdfpGuvvZYikQg1NDTQueeeS6+88or/M2KYFo6eARsOy+9E8TN01e+hkNw3FHK2q6yUx6msJCorI8rNdf/eWBAw05adtgE49NBDceqppwIALrvsMpSWluLWW28FAPzmN78BAOzYsQOVlZW48MIL9+xXU1MDAHj99dexaNEiAMDll1+O3/3udzHnWLZsGYqLi5GTIx/JfvvtF7PNG2+8gQ8++GDPWGpra1FYWIiPPvoIhx9+OHr06LFnjOXl5QldY1FREUKhEHr16oVvvvkGgHybeOmll9Avmi2yY8cOfPrppxg0aFBCx2aYTBK03LDXdl5ROfHCM814fLOksnp7GD9eRuwAsg1iJuLvFSzwAyCMNDj9e/v27QEAkUgEHTt2xNq1awMd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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Add image to tensorboard (plot the linear fit!)\n",
    "slope = sess.run(m)\n",
    "plot_buf = gen_linear_plot(slope[0])\n",
    "\n",
    "# Convert PNG buffer to TF image\n",
    "image = tf.image.decode_png(plot_buf.getvalue(), channels=4)\n",
    "\n",
    "# Add the batch dimension\n",
    "image = tf.expand_dims(image, 0)\n",
    "\n",
    "# Add image summary\n",
    "image_summary_op = tf.summary.image(\"Linear_Plot\", image)\n",
    "image_summary = sess.run(image_summary_op)\n",
    "log_writer.add_summary(image_summary, i)\n",
    "log_writer.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a href=\"url\"><img src=\"https://github.com/nfmcclure/tensorflow_cookbook/raw/master/11_More_with_TensorFlow/images/01_tensorboard3.png\" align=\"left\" height=\"450\" width=\"450\" ></a>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
